home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
MPW_C
/
TCPSTUFF
/
FINGER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-20
|
6KB
|
271 lines
/* HISTORY
MacTCP Finger tool
written by Matt Mashyna
Carnegie Mellon,
College of H&SS,
Macintosh Initiative.
Built from an ntp UDP example by Rob Chandok from CS
which was base on BSD 4.3
chandhok Tuesday, August 8, 1989 10:46:50 AM
Made name lookup on cacheFault work, added printf of host name on connection,
changed printf to puts, so a plan file with "%s" won't break this tool.
fixed bug in lf2sp that could miss a lf in the first byte of "s",
by changing while loop to a for loop.
mashyna Frisday, September 8, 1989 4:01:00 PM
Rebuilt foundation based on a standard H&SS TCP library.
Old calls that used a minimal Stream ref replaced by TCPiopb parameter blocks.
*/
#include <Types.h>
#include <Events.h>
#include <Math.h>
#include <fcntl.h>
#include <stdio.h>
#include <ErrMgr.h>
#include <CursorCtl.h>
#include <Errors.h>
#include <Devices.h>
#include <MacTCPCommonTypes.h>
#include <UDPPB.h>
#include <TCPPB.h>
#include <GetMyIPAddr.h>
#include <AddressXlation.h>
#include <signal.h>
#include <Time.h>
#include <tcplib.h>
extern char *malloc(), *strchr();
#define lf_char 10
#define cr_char 13
#define space_char 32
#define BUFSIZ 4096
#define TCPBUFSIZ 16384
void clean_exit(OSErr err, TCPiopb *tcppb); /* forward */
TCPiopb tcppb; /* global so we can abort via signal */
void choke(int sig)
{
#pragma unused(sig)
(void) TCPReleaseStream(tcppb.tcpStream,tcppb.ioCRefNum);
fprintf(stderr,"Finger aborted\n");
exit(0);
} /* close_listeners */
void FailOSErr(
char *msg,
OSErr err,
TCPiopb *tcppb)
{
if (err != noErr) {
fprintf(stderr,"%s errcode=%d\n",msg,err);
clean_exit (-1,tcppb);
}
}
pascal void dnrDone(struct hostInfo *hostInfoPtr, char *userDataPtr)
{
#pragma unused(hostInfoPtr)
(*userDataPtr)++;
}
void doDNRerr(OSErr err)
{
switch (err) {
case nameSyntaxErr:
fprintf(stderr,"(Bad syntax in host name)\n");
break;
case noNameServer:
fprintf(stderr,"(No name server can be found for this host)\n");
break;
case authNameErr:
fprintf(stderr,"(This domain/host name does not exist)\n");
break;
case noAnsErr:
fprintf(stderr,"(None of the name servers are responding)\n");
break;
case dnrErr:
fprintf(stderr,"(Unknown error from the domain name server)\n");
break;
}
}
char *inet_ntoa(ip_addr addr)
{
char dnrdoneflag;
static struct hostInfo hi;
OSErr err;
dnrdoneflag = 0;
err = AddrToName(addr,&hi,&dnrDone,&dnrdoneflag);
if (err == cacheFault) {
while (!dnrdoneflag) {
SpinCursor(1);
/* SystemTask? WaitNextEvent ? */
}
err = hi.rtnCode;
}
if (err == noErr) {
return hi.cname;
}
/* if all else fails */
if ((err = AddrToStr(addr,hi.cname)) != noErr) {
doDNRerr(err);
return "??";
} else {
return hi.cname;
}
}
void clean_exit(OSErr err, TCPiopb *tcppb)
{
(void) TCPReleaseStream(tcppb->tcpStream,tcppb->ioCRefNum);
if(err)
fprintf(stderr,"clean_exit(%d)\n",err);
(void) fflush(stderr);
exit(err);
}
main(argc, argv)
int argc;
char **argv;
{
char fbuff[BUFSIZ+1]; /* a read/write buffer */
int size; /* actual size to write, max size into and actual size of a read */
OSErr err; /* function return codes */
struct hostInfo hp;
short refnum;
char * host,
* user,
* p,
lastchar;
static char *noname = "\0";
char dnrdoneflag;
InitCursorCtl(nil);
if (argc < 2) {
fprintf(stderr,"Usage: %s [user@]host\n",argv[0]);
clean_exit(-1,&tcppb);
}
user = noname;
host = noname;
p = strchr(argv[1],'@');
if(p) {
user = argv[1];
*p='\0';
host = p+1;
}
bzero((char *)&tcppb,sizeof(tcppb));
if(strlen(host) == 0) {
fprintf(stderr,"No host specified\n");
clean_exit(-1,&tcppb);
}
if(OpenResolver(NIL)) {
fprintf(stderr,"Failed to open resolver\n");
exit(0);
}
if(opendriver(".IPP",&refnum)) {
fprintf(stderr,"Failed to open IP driver\n");
exit(0);
}
dnrdoneflag = 0;
err = StrToAddr(host,&hp,&dnrDone,&dnrdoneflag);
if (err == cacheFault) {
while (!dnrdoneflag) {
SpinCursor(1);
/* SystemTask? WaitNextEvent ? */
}
err = hp.rtnCode;
}
/* check for uncaught error in dnr! */
if ((err == noErr) && (hp.addr[0] == 0)) {
err = dnrErr;
}
if (err != noErr) {
fprintf(stderr, "\nNo such host: %s error:%d\n", host,err);
doDNRerr(err);
clean_exit(-1,&tcppb);
}
sprintf(fbuff,"%s\r\n",user); /* finger expects to have CR & LF after the name */
size = BUFSIZ;
tcppb.ioCRefNum = refnum;
(void) signal(SIGINT,choke);
FailOSErr("Create Stream",CreateTCPStream(TCPBUFSIZ,&tcppb),&tcppb); /* create a port to use with TCPBUFSIZ size buffer */
fprintf(stdout,"[%s]\n",inet_ntoa(hp.addr[0])); /* show that we are connected to the host */
(void) fflush(stdout); /* make sure it shows up*/
FailOSErr("Open Stream",OpenTCPStream(FINGER_PORT,&hp,&tcppb),&tcppb); /* now open a connection with the other host */
FailOSErr("Write Stream",WriteTCPStream(fbuff,&size,&tcppb,false),&tcppb); /* send it our finger request */
if (err == ipDestDeadErr) { /* are there other codes here we should special case? */
fprintf(stderr,"Host %s not responding, errcode=%d\n",inet_ntoa(hp.addr[0]),err);
clean_exit(0,&tcppb);
}
else if (err != noErr) {
fprintf(stderr,"TCPsend fails errcode=%d\n",err);
clean_exit(0,&tcppb);
}
Show_Cursor(WATCH_CURSOR); /* wait for the host to reply */
while(err != connectionClosing && err != commandTimeout) { /* loop until host has no more to send */
size = BUFSIZ;
err = ReadTCPStream(fbuff,&size,&tcppb,false); /* read from remote host */
if (err == commandTimeout) {
fprintf(stderr,"\n\t* Timeout *\n");
clean_exit(0,&tcppb);
}
else if (err == connectionClosing) continue; /* will be caught in loop above */
else if (err != noErr) {
fprintf(stderr,"packet:TCPRead fails (%d)\n", err);
clean_exit(0,&tcppb);
}
for (lastchar = 0, p = fbuff; p < fbuff+size; p++) {
switch (*p) {
case lf_char:
if (lastchar == cr_char) {
/* skip the lf */
}
break;
default:
putchar(*p);
}
lastchar = *p;
}
(void) fflush(stdout); /* make sure it shows up*/
}
clean_exit(0,&tcppb);
} /* end of main */